/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cashmate.hibernate.dao;

import com.cashmate.hibernate.pojo.Areas;
import com.cashmate.hibernate.pojo.Collections;
import com.cashmate.hibernate.pojo.Documents;
import com.cashmate.hibernate.pojo.Payments;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.LinkedList;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;

/**
 *
 * @author Dine
 */
public class CollectionsDAO extends DAO {

    public CollectionsDAO() {
        super();
    }

    //BASIC DAO METHODS
    @SuppressWarnings("unchecked")
    public List<Collections> getAll() throws Exception {
        List<Collections> a = (List<Collections>) getSession().createQuery("from Collections a").setCacheable(true).list();
        flush();
        return a;
    }

    @SuppressWarnings("unchecked")
    public Collections get(int id) throws Exception {
        Collections a = (Collections) getSession().createQuery("from Collections a where a.collectionid=:id").setParameter("id", id).setCacheable(true).uniqueResult();
        flush();
        return a;
    }

    @SuppressWarnings("unchecked")
    public void update(Collections a) throws Exception {
        try {
            begin();
            getSession().update(a);
            commit();
            flush();
        } catch (Exception e) {
            rollback();
            throw e;
        }
    }

    @SuppressWarnings("unchecked")
    public void insert(Collections a) throws Exception {
        try {
            begin();
            getSession().save(a);
            commit();
            flush();
        } catch (Exception e) {
            rollback();
            throw e;
        }
    }

    @SuppressWarnings("unchecked")
    public void delete(int id) throws Exception {
        try {
            begin();
            getSession().delete(get(id));
            commit();
            flush();
        } catch (Exception e) {
            rollback();
            throw e;
        }
    }

    @SuppressWarnings("unchecked")
    public List<Collections> findByCriteria(DetachedCriteria dc, int from, int size) throws Exception {
        Criteria criteria = dc.getExecutableCriteria(getSession());
        criteria.setFirstResult(from);
        criteria.setMaxResults(size);
        criteria.setCacheable(true);
        List<Collections> list = criteria.list();
        flush();
        return list;
    }

    @SuppressWarnings("unchecked")
    public int countByCriteria(DetachedCriteria dc) throws Exception {
        Criteria criteria = dc.getExecutableCriteria(getSession());
        criteria.setCacheable(true);
        criteria.setProjection(Projections.rowCount());
        int count = ((Integer) criteria.list().get(0)).intValue();
        flush();
        return count;
    }

    @SuppressWarnings("unchecked")
    public String getLatestCollectionDate() throws Exception {
        Collections c = (Collections) getSession().createQuery("from Collections c order by c.date desc").setMaxResults(1).setCacheable(true).uniqueResult();
        flush();
        return c.getDate();
    }

    @SuppressWarnings("unchecked")
    public Collections getLastCollection() throws Exception {
        Collections c = (Collections) getSession().createQuery("from Collections c order by c.collectionid desc").setMaxResults(1).setCacheable(true).uniqueResult();
        flush();
        return c;
    }

    @SuppressWarnings("unchecked")
    public ArrayList<Collections> getByCriteria(DetachedCriteria dc) throws Exception {
        Criteria criteria = dc.getExecutableCriteria(getSession());
        criteria.setCacheable(true);
        ArrayList arr = new ArrayList<Collections>(criteria.list());
        return arr;
    }

// USE insert(Collections a) above...
//    @SuppressWarnings("unchecked")
//    public void addCollection(Collections coll) throws Esception{
//        try {
//
//            getSession().saveOrUpdate(coll);
//            transaction.commit();
//            session.flush();
//        } catch (Exception e) {
//            System.out.println("TRANSACTIONcoll " + e.toString());
//            transaction.rollback();
//
//        }
//    }
// USE get(int id) above...
//    public Collections getByCollectionID(int id) {
//        Collections c = null;
//        try {
//            c = (Collections) session.createQuery("from Collections c where c.collectionid=:id").setParameter("id", id).setMaxResults(1).uniqueResult();
//        } catch (Exception e) {
//            return null;
//        }
//        return c;
//    }
     @SuppressWarnings("unchecked")
    public String saveCollection(Collections coll, Documents document, List<Payments> payment, HashMap<Integer, Double> loans, HashMap<Integer, Double> overdue, HashMap<Integer, Integer> daysleft) throws Exception{
        try {
            Session session = getSession();
            begin();
            session.saveOrUpdate(document);
            session.saveOrUpdate(coll);

            for (int i = 0; i < payment.size(); i++) {
                session.save(payment.get(i));
            }

            for (Map.Entry<Integer, Double> entry : loans.entrySet()) {
                session.createQuery("update Loans set balance =:balance where loanid=:loanid").setParameter("balance", entry.getValue()).setParameter("loanid", entry.getKey()).executeUpdate();
            }

            for (Map.Entry<Integer, Double> entry : overdue.entrySet()) {
                session.createQuery("update Loans set overdue =:overdue where loanid=:loanid").setParameter("overdue", entry.getValue()).setParameter("loanid", entry.getKey()).executeUpdate();
            }

            for (Map.Entry<Integer, Integer> entry : daysleft.entrySet()) {
                session.createQuery("update Loans set daysleft =:daysleft where loanid=:loanid").setParameter("daysleft", entry.getValue()).setParameter("loanid", entry.getKey()).executeUpdate();
            }

            commit();
            flush();
            return "ok";
        } catch (Exception e) {
            System.out.println("TRANSACTIONdep: " + e.toString());
            rollback();
            e.printStackTrace();
            return e.toString();
        }
    }

    public String updateCollection(Collections coll, Documents document, List<Payments> payment) throws Exception {
        try {
            Session session = getSession();
            begin();
            session.saveOrUpdate(document);
            session.saveOrUpdate(coll);

            for (int i = 0; i < payment.size(); i++) {
                session.saveOrUpdate(payment.get(i));
            }
            commit();
            flush();
            return "ok";
        } catch (Exception e) {
            rollback();
            throw e;
        }
    }

    public List<Collections> getCCRCollection(String date, List<Areas> arealist) throws Exception {
        List<Collections> list = new LinkedList<Collections>();
        int areaid;

        //System.out.println(date);

        for (Areas a : arealist) {
            areaid = a.getAreaid();
            //System.out.println(areaid);
            Collections coll = (Collections) getSession().createQuery("from Collections a where a.date=:date and a.areas.areaid=:areaid").setParameter("date", date).setParameter("areaid", areaid).setMaxResults(1).setCacheable(true).uniqueResult();
            if (coll != null) {
                list.add(coll);
            }
        }
        flush();
        //System.out.println("ccrcoll:" + list);
        return list;

    }
    
     public Collections getByAreaCodeAndDate(String areacode, String date){
        try {
            Collections coll;
            coll = (Collections) getSession().createQuery("from Collections a where a.date=:date and a.areas.areacode=:areacode").setParameter("date", date).setParameter("areacode", areacode).setMaxResults(1).uniqueResult();
            return coll;
        } catch (Exception e) {
            System.out.println("collerr:" + e.toString());
            return null;
        }
    }
}
